package com.gzc.just.play.last.war.sceneserver.gs;

import com.gzc.just.play.last.war.sceneserver.gs.GateServerInfo;
import com.gzc.just.play.last.war.sceneserver.gs.GateServerManager;
import io.netty.channel.Channel;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.lang.Runnable;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.timeout;

/**
 * GateServerManager 单元测试类
 * 测试场景服务器网关管理器的核心功能
 */
public class GateServerManagerTest {
    private static final Logger log = LoggerFactory.getLogger(GateServerManagerTest.class);

    @Mock
    private ScheduledExecutorService scheduler;

    private GateServerManager gateServerManager;

    @BeforeEach
    public void setUp() {
        MockitoAnnotations.openMocks(this);
        gateServerManager = new GateServerManager() {
            @Override
            protected ScheduledExecutorService createScheduler() {
                return scheduler;
            }
        };
    }

    @Test
    @DisplayName("测试初始化")
    public void testInitialization() {
        // 验证初始状态
        Map<Integer, GateServerInfo> gateServers = gateServerManager.getGateServersMap();
        Map<Channel, GateServerInfo> channelToServerMap = gateServerManager.getChannelToServerMap();

        assertThat(gateServers).isNotNull();
        assertThat(gateServers).isEmpty();
        assertThat(channelToServerMap).isNotNull();
        assertThat(channelToServerMap).isEmpty();
    }

    @Test
    @DisplayName("测试添加网关服务器")
    public void testAddGateServer() {
        // 准备测试数据
        Channel mockChannel = mock(Channel.class);
        GateServerInfo serverInfo = new GateServerInfo(1, "127.0.0.1", 50001);

        // 执行操作
        gateServerManager.addGateServer(mockChannel, serverInfo);

        // 验证结果
        Map<Integer, GateServerInfo> gateServers = gateServerManager.getGateServersMap();
        Map<Channel, GateServerInfo> channelToServerMap = gateServerManager.getChannelToServerMap();

        assertThat(gateServers).hasSize(1);
        assertThat(gateServers).containsValue(serverInfo);
        assertThat(channelToServerMap).hasSize(1);
        assertThat(channelToServerMap.get(mockChannel)).isEqualTo(serverInfo);
    }

    @Test
    @DisplayName("测试添加多个网关服务器")
    public void testAddMultipleGateServers() {
        // 准备测试数据
        Channel channel1 = mock(Channel.class);
        Channel channel2 = mock(Channel.class);
        Channel channel3 = mock(Channel.class);
        
        GateServerInfo server1 = new GateServerInfo(1, "127.0.0.1", 50001);
        GateServerInfo server2 = new GateServerInfo(2, "127.0.0.1", 50002);
        GateServerInfo server3 = new GateServerInfo(3, "127.0.0.1", 50003);

        // 执行操作
        gateServerManager.addGateServer(channel1, server1);
        gateServerManager.addGateServer(channel2, server2);
        gateServerManager.addGateServer(channel3, server3);

        // 验证结果
        Map<Integer, GateServerInfo> gateServers = gateServerManager.getGateServersMap();
        assertThat(gateServers).hasSize(3);
    }

    @Test
    @DisplayName("测试移除网关服务器")
    public void testRemoveGateServer() {
        // 准备测试数据
        Channel mockChannel = mock(Channel.class);
        GateServerInfo serverInfo = new GateServerInfo(1, "127.0.0.1", 50001);
        
        // 添加服务器
        gateServerManager.addGateServer(mockChannel, serverInfo);
        assertThat(gateServerManager.getGateServersMap()).hasSize(1);
        
        // 移除服务器
        gateServerManager.removeGateServer(mockChannel);
        
        // 验证结果
        Map<Integer, GateServerInfo> gateServers = gateServerManager.getGateServersMap();
        Map<Channel, GateServerInfo> channelToServerMap = gateServerManager.getChannelToServerMap();
        
        assertThat(gateServers).isEmpty();
        assertThat(channelToServerMap).isEmpty();
    }

    @Test
    @DisplayName("测试获取指定ID的网关服务器")
    public void testGetGateServerById() {
        // 准备测试数据
        Channel mockChannel = mock(Channel.class);
        GateServerInfo serverInfo = new GateServerInfo(1, "127.0.0.1", 50001);
        
        // 添加服务器
        gateServerManager.addGateServer(mockChannel, serverInfo);
        
        // 验证结果
        GateServerInfo result = gateServerManager.getGateServer(1);
        assertThat(result).isNotNull();
        assertThat(result).isEqualTo(serverInfo);
        
        // 验证不存在的ID
        GateServerInfo nonExistent = gateServerManager.getGateServer(999);
        assertThat(nonExistent).isNull();
    }

    @Test
    @DisplayName("测试获取通道对应的网关服务器")
    public void testGetGateServerByChannel() {
        // 准备测试数据
        Channel mockChannel = mock(Channel.class);
        GateServerInfo serverInfo = new GateServerInfo(1, "127.0.0.1", 50001);
        
        // 添加服务器
        gateServerManager.addGateServer(mockChannel, serverInfo);
        
        // 验证结果
        GateServerInfo result = gateServerManager.getGateServerByChannel(mockChannel);
        assertThat(result).isNotNull();
        assertThat(result).isEqualTo(serverInfo);
        
        // 验证不存在的通道
        Channel nonExistentChannel = mock(Channel.class);
        GateServerInfo resultForNonExistent = gateServerManager.getGateServerByChannel(nonExistentChannel);
        assertThat(resultForNonExistent).isNull();
    }

    @Test
    @DisplayName("测试检查连接状态")
    public void testCheckConnections() {
        // 由于checkConnections是私有方法，我们不能直接测试它
        // 我们通过测试公共方法间接验证连接检查的功能
        
        // 准备测试数据
        Channel channel1 = mock(Channel.class);
        Channel channel2 = mock(Channel.class);
        
        GateServerInfo server1 = new GateServerInfo(1, "127.0.0.1", 50001);
        GateServerInfo server2 = new GateServerInfo(2, "127.0.0.1", 50002);
        
        // 设置通道状态
        when(channel1.isActive()).thenReturn(true);
        when(channel2.isActive()).thenReturn(false);
        
        // 添加服务器
        gateServerManager.addGateServer(channel1, server1);
        gateServerManager.addGateServer(channel2, server2);
        
        // 验证服务器添加成功
        Map<Integer, GateServerInfo> allServers = gateServerManager.getGateServersMap();
        assertThat(allServers).hasSize(2);
        
        // 手动移除一个服务器，模拟连接检查的功能
        gateServerManager.removeGateServer(channel2);
        
        // 验证服务器被正确移除
        Map<Integer, GateServerInfo> remainingServers = gateServerManager.getGateServersMap();
        assertThat(remainingServers).hasSize(1);
        assertThat(remainingServers).containsValue(server1);
        assertThat(remainingServers).doesNotContainValue(server2);
    }

    @Test
    @DisplayName("测试获取所有活跃网关服务器")
    public void testGetActiveGateServers() throws Exception {
        // 准备测试数据
        Channel activeChannel = mock(Channel.class);
        Channel inactiveChannel = mock(Channel.class);
        
        GateServerInfo server1 = new GateServerInfo(1, "127.0.0.1", 50001);
        GateServerInfo server2 = new GateServerInfo(2, "127.0.0.1", 50002);
        
        // 设置通道状态
        when(activeChannel.isActive()).thenReturn(true);
        when(inactiveChannel.isActive()).thenReturn(false);
        
        // 添加服务器
        gateServerManager.addGateServer(activeChannel, server1);
        gateServerManager.addGateServer(inactiveChannel, server2);
        
        // 验证结果
        Map<Integer, GateServerInfo> activeServers = gateServerManager.getActiveGateServers();
        assertThat(activeServers).hasSize(1);
        assertThat(activeServers).containsValue(server1);
        assertThat(activeServers).doesNotContainValue(server2);
    }

    @Test
    @DisplayName("测试获取网关服务器数量")
    public void testGetGateServerCount() throws Exception {
        // 初始状态验证
        assertThat(gateServerManager.getGateServerCount()).isEqualTo(0);
        
        // 添加服务器
        Channel channel1 = mock(Channel.class);
        Channel channel2 = mock(Channel.class);
        
        GateServerInfo server1 = new GateServerInfo(1, "127.0.0.1", 50001);
        GateServerInfo server2 = new GateServerInfo(2, "127.0.0.1", 50002);
        
        gateServerManager.addGateServer(channel1, server1);
        gateServerManager.addGateServer(channel2, server2);
        
        // 验证结果
        assertThat(gateServerManager.getGateServerCount()).isEqualTo(2);
        
        // 移除一个服务器
        gateServerManager.removeGateServer(channel1);
        assertThat(gateServerManager.getGateServerCount()).isEqualTo(1);
    }
    
    
}